//给定2D空间中四个点的坐标 p1, p2, p3 和 p4，如果这四个点构成一个正方形，则返回 true 。 
//
// 点的坐标 pi 表示为 [xi, yi] 。输入 不是 按任何顺序给出的。 
//
// 一个 有效的正方形 有四条等边和四个等角(90度角)。 
//
// 
//
// 示例 1: 
//
// 
//输入: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
//输出: True
// 
//
// 示例 2: 
//
// 
//输入：p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,12]
//输出：false
// 
//
// 示例 3: 
//
// 
//输入：p1 = [1,0], p2 = [-1,0], p3 = [0,1], p4 = [0,-1]
//输出：true
// 
//
// 
//
// 提示: 
//
// 
// p1.length == p2.length == p3.length == p4.length == 2 
// -10⁴ <= xi, yi <= 10⁴ 
// 
//
// Related Topics 几何 数学 👍 93 👎 0

package leetcode.editor.cn;

import java.util.Arrays;

public class _593_ValidSquare {
    public static void main(String[] args) {
//        int[] p1 = {0, 0};
//        int[] p2 = {1, 1};
//        int[] p3 = {1, 0};
//        int[] p4 = {0, 1};
        int[] p1 = {0, 0};
        int[] p2 = {-1, 0};
        int[] p3 = {1, 0};
        int[] p4 = {0, 1};
        Solution solution = new _593_ValidSquare().new Solution();
        System.out.println(solution.validSquare(p1, p2, p3, p4));
    }

    class Solution {
        public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) {
            if (Arrays.equals(p1, p2)) {
                return false;
            }
            if (help(p1, p2, p3, p4)) {
                return true;
            }

            if (Arrays.equals(p1, p3)) {
                return false;
            }
            if (help(p1, p3, p2, p4)) {
                return true;
            }

            if (Arrays.equals(p1, p4)) {
                return false;
            }
            if (help(p1, p4, p2, p3)) {
                return true;
            }
            return false;
        }

        private boolean help(int[] p1, int[] p2, int[] p3, int[] p4) {
            int[] v1 = {p1[0] - p2[0], p1[1] - p2[1]};
            int[] v2 = {p3[0] - p4[0], p3[1] - p4[1]};
            if (checkMidPoint(p1, p2, p3, p4) && checkLength(v1, v2) && calCos(v1, v2)) {
                return true;
            }
            return false;
        }

        private boolean calCos(int[] v1, int[] v2) {
            return (v1[0] * v2[0] + v1[1] * v2[1]) == 0;
        }

        private boolean checkLength(int[] v1, int[] v2) {
            return (v1[0] * v1[0] + v1[1] * v1[1]) == (v2[0] * v2[0] + v2[1] * v2[1]);
        }

        private boolean checkMidPoint(int[] p1, int[] p2, int[] p3, int[] p4) {
            return (p1[0] + p2[0]) == (p3[0] + p4[0]) && (p1[1] + p2[1]) == (p3[1] + p4[1]);
        }
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution1 {
        public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) {
            int[] xiangLiang1 = xiangLiang(p1, p2);
            int[] xiangLiang2 = xiangLiang(p3, p4);
            if (getLength(xiangLiang1) == getLength(xiangLiang2) && dianCheng(xiangLiang1, xiangLiang2) == 0) {
                return getLength(xiangLiang1) == 0 ? false : true;
            }
            xiangLiang1 = xiangLiang(p1, p3);
            xiangLiang2 = xiangLiang(p2, p4);
            if (getLength(xiangLiang1) == getLength(xiangLiang2) && dianCheng(xiangLiang1, xiangLiang2) == 0) {
                return getLength(xiangLiang1) == 0 ? false : true;
            }
            xiangLiang1 = xiangLiang(p1, p4);
            xiangLiang2 = xiangLiang(p2, p3);
            if (getLength(xiangLiang1) == getLength(xiangLiang2) && dianCheng(xiangLiang1, xiangLiang2) == 0) {
                return getLength(xiangLiang1) == 0 ? false : true;
            }
            return false;
        }

        private int[] xiangLiang(int[] p1, int[] p2) {
            return new int[]{p1[0] - p2[0], p1[1] - p2[1]};
        }

        private int dianCheng(int[] p1, int[] p2) {
            return p1[0] * p2[0] + p1[1] * p2[1];
        }

        private double getLength(int[] p) {
            return Math.sqrt(p[0] * p[0] + p[1] * p[1]);
        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}